package cn.rengy.tpa.wxmp.component.auth;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

import cn.rengy.tool.http.HttpUtils;
import cn.rengy.tpa.wxmp.exception.WeChatException;
import cn.rengy.tpa.wxmp.token.AccessToken;

/**
 * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1453779503&token=209576a955e1861d95876efe59caed2792c212e0&lang=zh_CN
 * @author rengy
 *
 */
public class ComponentAccessTokenApi {
	private static Logger logger = LoggerFactory.getLogger(ComponentAccessTokenApi.class);
	private static final String URL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
	private static final String QUERY_AUTH_URL="https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=";
	private static final String REFRESH_TOKEN_URL="https:// api.weixin.qq.com /cgi-bin/component/api_authorizer_token?component_access_token=";
	
	public static ComponentAccessTokenResponse getComponentAccessToken(String component_appid,String component_appsecret,String component_verify_ticket) throws WeChatException{
		ComponentAccessTokenResponse componentAccessTokenResponse=null;
		JSONObject postObject = new JSONObject();
		postObject.put("component_appid", component_appid);
		postObject.put("component_appsecret", component_appsecret);
		postObject.put("component_verify_ticket", component_verify_ticket);
		String httpResult = HttpUtils.post(URL, postObject.toJSONString());
		logger.debug(httpResult);
		JSONObject result = JSONObject.parseObject(httpResult);
		//{"errcode":61005,"errmsg":"component ticket is expired hint: [ZHRC2a07362790]"}
		//{"errcode":61004,"errmsg":"access clientip is not registered hint: [TA4WCa04573612] requestIP: 183.184.50.125"}
		int errcode=result.getIntValue("errcode");
		if(errcode!=0){
			String errmsg=result.getString("errmsg");
			throw new WeChatException(errcode,errmsg);
		}
		String component_access_token=result.getString("component_access_token");
		int expires_in=result.getIntValue("expires_in");
		componentAccessTokenResponse= new ComponentAccessTokenResponse(component_access_token,  expires_in);
		return componentAccessTokenResponse;
	}
	
	/**
	 * 该API用于使用授权码换取授权公众号或小程序的授权信息，
	 * 并换取authorizer_access_token和authorizer_refresh_token。
	 *  授权码的获取，需要在用户在第三方平台授权页中完成授权流程后，
	 *  在回调URI中通过URL参数提供给第三方平台方。
	 *  请注意，由于现在公众号或小程序可以自定义选择部分权限授权给第三方平台，
	 *  因此第三方平台开发者需要通过该接口来获取公众号或小程序具体授权了哪些权限，
	 * 而不是简单地认为自己声明的权限就是公众号或小程序授权的权限。
	 * @param accessToken 第三方平台accessToken
	 * @param component_appid 第三方平台appid
	 * @param authorization_code 授权code,会在授权成功时返回给第三方平台
	 * @return
	 * @throws WeChatException 
	 */
	public static AuthorizerAccessTokenResponse getAuthorizerAccessToken(AccessToken accessToken,String component_appid,String authorization_code) throws WeChatException{
		AuthorizerAccessTokenResponse authorizerAccessTokenResponse=null;
		JSONObject postObject = new JSONObject();
		postObject.put("component_appid", component_appid);
		postObject.put("authorization_code", authorization_code);
		String postData=postObject.toJSONString();
		for(int i=0;i<2;i++){
			String resultStr = HttpUtils.post(QUERY_AUTH_URL+accessToken.token(),postData);
			logger.debug("getAuthorizerAccessToken:{}",resultStr);
			JSONObject jsonObject = JSONObject.parseObject(resultStr);
			int errCode =jsonObject.getIntValue("errcode");
			if(errCode==0){
				authorizerAccessTokenResponse=JSONObject.parseObject(resultStr, AuthorizerAccessTokenResponse.class);
				return authorizerAccessTokenResponse;
			}else if(errCode==40001){
				accessToken.refresh();
			}else{
				String errmsg=jsonObject.getString("errmsg");
				throw new WeChatException(errCode,errmsg);
			}
		}
		return authorizerAccessTokenResponse;
	}
	/**
	 * 获取（刷新）授权公众号或小程序的接口调用凭据（令牌）
	 * @param component_appid 第三方平台appid
	 * @param authorizer_appid 授权方appid
	 * @param authorizer_refresh_token 授权方的刷新令牌，刷新令牌主要用于第三方平台获取和刷新已授权用户的access_token，只会在授权时刻提供，请妥善保存。一旦丢失，只能让用户重新授权，才能再次拿到新的刷新令牌
	 * @throws WeChatException 
	 */
	public static RefreshTokenResponse refreshAuthorizerAccessToken(AccessToken accessToken,String component_appid,String authorizer_appid,String authorizer_refresh_token) throws WeChatException{
		RefreshTokenResponse refreshTokenResponse=null;
		JSONObject postObject = new JSONObject();
		postObject.put("component_appid", component_appid);
		postObject.put("authorizer_appid", authorizer_appid);
		postObject.put("authorizer_refresh_token", authorizer_refresh_token);
		String postData=postObject.toJSONString();
		for(int i=0;i<2;i++){
			String resultStr = HttpUtils.post(REFRESH_TOKEN_URL+accessToken.token(),postData);
			logger.debug("refreshAuthorizerAccessToken:{}",resultStr);
			JSONObject jsonObject = JSONObject.parseObject(resultStr);
			int errCode =jsonObject.getIntValue("errcode");
			if(errCode==0){
				refreshTokenResponse=JSONObject.parseObject(resultStr, RefreshTokenResponse.class);
				return refreshTokenResponse;
			}else if(errCode==40001){
				accessToken.refresh();
			}else{
				String errmsg=jsonObject.getString("errmsg");
				throw new WeChatException(errCode,errmsg);
			}
		}
		return null;
	}
}
